package pers.cz.logtail;

import io.netty.channel.ChannelFuture;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pers.cz.config.JefConfiguration;
import pers.cz.exception.ErrorCode;
import pers.cz.exception.RegisterException;
import pers.cz.logtail.annotation.AutoRegistServiceManager;
import pers.cz.logtail.config.LogClientConfigItem;
import pers.cz.logtail.config.RegeditTypeEnum;
import pers.cz.logtail.config.RegisterConfigEnum;
import pers.cz.logtail.handler.FileLineConsumer;
import pers.cz.logtail.handler.LogListenner;
import pers.cz.logtail.regedit.ServiceRegedit;
import pers.cz.netty.client.NettyClient;
import pers.cz.netty.client.TcpNettyClient;
import pers.cz.netty.client.UdpNettyClient;
import pers.cz.netty.config.NettyConfigItem;
import pers.cz.tools.StringUtils;
import pers.cz.util.FileUtils;

import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: PostGirl-panent
 * @description: 客户端启动类
 * @author: Cheng Zhi
 * @create: 2022-10-05 12:16
 **/
public class ClientApplication {

    public static Logger logger = LoggerFactory.getLogger(ClientApplication.class);

    public static final String SERVER_NAME = "LOGTAILSERVER";

    public static void main(String[] args) throws Exception {
        // 启动netty客户端
        //String host = JefConfiguration.get(NettyConfigItem.NETTY_SERVER_IP);
        //int port = JefConfiguration.getInt(NettyConfigItem.NETTY_SERVER_PORT, 4567);

        init();

        String service = getService(); // 获取服务，获取到的服务地址为ip:port
        String[] split = StringUtils.split(service, ":");
        String host = split[0];
        int port = Integer.valueOf(split[1]);
        NettyClient nettyClient = null;
        if ("UDP".equalsIgnoreCase(JefConfiguration.get(NettyConfigItem.NETTY_TYPE, "TCP"))) {
            nettyClient =  new UdpNettyClient(host, port);
        } else {
            nettyClient =  new TcpNettyClient(host, port);
        }
        ChannelFuture connect = nettyClient.connect();
        if (connect.sync().isSuccess()) {

            // 启动消费者
            FileLineConsumer thread = new FileLineConsumer(nettyClient);
            thread.start();
            String listenPath = JefConfiguration.get(LogClientConfigItem.LOG_LISTEN_FILEPATH);
            String symbol = JefConfiguration.get(LogClientConfigItem.LOG_SPLIT_SYMBOL, ";");
            // 轮询间隔 5 秒
            long interval = TimeUnit.SECONDS.toMillis(JefConfiguration.getLong(LogClientConfigItem.LOG_LISTEN_INTERVALUE_TIME, 5));
            FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
            // 使用分号分割
            String[] paths = StringUtils.split(listenPath, symbol);
            Map<String, Long> fileLineRember = new HashMap<>();
            Map<String, RandomAccessFile> fileRandowNote = new HashMap<>();
            LogListenner logListenner = new LogListenner(fileLineRember,fileRandowNote );
            for (String path : paths) {
                FileAlterationObserver observer = FileUtils.getFileObServer(path);
                //设置文件变化监听器
                observer.addListener(logListenner);
                monitor.addObserver(observer);
            }
            monitor.start();
        }
    }

    private static void init() {
        // 自动添加注册中心
        new AutoRegistServiceManager().registe();
    }


    /**
     * 把当前服务地址注册到注册中心
     */
    private static String getService()  {
        try {
            String registerType = JefConfiguration.get(RegisterConfigEnum.REGISTER_TYPE);
            ServiceRegedit serviceRegeditInstance = RegeditTypeEnum.getServiceRegeditInstance(registerType);
            return serviceRegeditInstance.getService(SERVER_NAME);
        } catch (Exception e) {
            logger.error("获取注册中心服务失败，请修改配置", e);
            throw new RegisterException(ErrorCode.GET_SERVICE_ERROR);
        }
    }
}
